home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
020a
/
tvg102_s.zip
/
TVGRAPH.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-04-02
|
22KB
|
845 lines
{$A-,B-,D+,E+,F+,G-,I+,L+,N-,O-,R-,S-,V-,X-}
{$M 16384,0,655360}
{$DEFINE DEMO}
unit TvGraph;
(* Include this unit before any other TVision unit and the program will *)
(* Work entirely in graphics mode and look identical ( although slower) *)
(* to the original text display. Using this in conjunction with a *)
(* companion unit TVGOBJ, will allow you to do graphics using the full *)
(* capability of TURBO VISION Menus,Dialog boxes etc. *)
interface
uses
Drivers,Objects,Views;
const
GraphXMax=10000;
GraphYMax=07500;
smEGA = $0010;
smVGA = $0012;
smGraphAutoDetect=$00FF; (* Autodetect *)
wrmOVERWRITE = 0;
wrmAND = 1;
wrmOR = 2;
wrmXOR = 3;
type
PGRect=^GRect;
GRect=Trect;
PGPoint=^GPoint;
GPoint=TPoint;
function NextGraphId:byte;
procedure UseGraphId(b:byte);
procedure ReleaseGraphId(b:byte);
procedure TextToGraphics(T:TRect;var G:Grect);
procedure RawDrawLine(X1,Y1,X2,Y2:integer;Color:word);
procedure DrawLine(X1,Y1,X2,Y2:integer;Color:word);
function ISin(X:integer):integer;
function ICos(X:integer):integer;
implementation
const
(********************************************************************)
(* *)
(* CRITICAL - WARNING LOOK AT THIS CONSTANT - VERSION DEPENDANT *)
(* *)
(********************************************************************)
OfsFromInit=$261-$222;
(* Offset between where the Views.Tview.Init procedure is and where *)
(* the code starts for the Checksnow = TRUE code *)
(* This value is absolutely critical and may change between *)
(* Turbovision releases WATCH OUT CRITICAL *)
CurrentGraphWindow:byte=1;
CurrentLineStyle:word=$FFFF;
(* Current Line style in 1=line 0=no line *)
CurrentLineWriteMode:byte=$00;
(* Current Write mode for lines *)
SineTable:array[0..180] of integer=
(0,9,18,27,36,45,54,63,71,80,89,98,107,116,125,134,143,151,160,169,178,
187,195,204,213,222,230,239,248,256,265,274,282,291,299,308,316,325,333,
342,350,359,367,375,384,392,400,408,416,425,433,441,449,457,465,473,481,
489,496,504,512,520,527,535,543,550,558,565,573,580,587,595,602,609,616,
623,630,637,644,651,658,665,672,679,685,692,698,705,711,718,724,730,737,
743,749,755,761,767,773,779,784,790,796,801,807,812,818,823,828,834,839,
844,849,854,859,864,868,873,878,882,887,891,896,900,904,908,912,916,920,
924,928,932,935,939,943,946,949,953,956,959,962,965,968,971,974,977,979,
982,984,987,989,991,994,996,998,1000,1002,1003,1005,1007,1008,1010,1011,
1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1022,1023,1023,1023,
1024,1024,1024,1024);
type
{$IFDEF DEMO}
Vector = record X1,Y1,X2,Y2:word; end;
{$ENDIF}
ABitFont = array[0..255] of array[0..15] of byte;
(* Store upto 32 line high font *)
PAbitFont = ^ABitFont;
(* The pointer to a copy of the currently in use font *)
PtrRec = record O,S:word; end; (* used to separate Ofs and Seg *)
var
(* All the hardware dependant routines called indirectly *)
Do_INIT_X:procedure;
Do_DONE_X:Procedure;
TVGraphCursorOn_X,
TVGraphCursorOff_X,
TVUpdateCursor_X,
Do_GraphMOV_X,
NewJmp_GraphMOV_X:pointer;
Draw_Any_Line_X:procedure (X1,Y1,X2,Y2:word;Color:byte);
Draw_Horiz_Line_X:procedure (X1,X2,Y:word;Color:byte);
Draw_Vert_Line_X:procedure (X,Y1,Y2:word;Color:byte);
P1,P2:Pointer; (* General pointers used for copies *)
BytesPerLine:word; (* Bytes per line in graphics mode *)
VideoBufferSeg:word; (* Video Segment for display *)
GTVEventRoutine:PtrRec;
(* Address of TVision mouse event handler *)
GTVEventMask:word; (* Mask as passed by call to handler install *)
OldINT33h,OldINT10h:Pointer;
(* Old pointers to call for INT 33 and INT 10 *)
Int33h:Pointer absolute $0000:$00CC;
(* INT 33h actual address *)
Int10h:Pointer absolute $0000:$0040;
(* INT 10h actual address *)
RomFont:PABitFont absolute $0000:$010C;
(* Address of current FONT *)
ColorList:word; (* Pointer to List of color masks in EGA memory *)
Count:word; (* Counts down the number of char's in GRAPHMOV *)
DestOfs:word; (* Destination in EGA of the current mask *)
TextSource:PtrRec; (* Source for next Ch/Attr pair *)
TextDest:word; (* Normal destination for text 0..screen size *)
SaveJump:word; (* Save jump location for GraphMov *)
TvGraphLoc,TvGraphCursor:word;
(* Store current text x,y and top/bottom cursor *)
GraphMouseLoc:TPoint; (* Graphics location of Mouse *)
TvViziFlag:byte; (* Toggles ON=FF and OFF=00 for cursor *)
FontTable:ABitFont; (* In Memory font table *)
PtrFontTable:PABitFont;(* Pointer to In Memory font table *)
GraphWriteAvail:array[0..4095] of byte;
(* one byte for each text position on the screen, 0=text screen and *)
(* a number 1-254 representing distinct graphics windows and 255 *)
(* represents the mouse cursor positions *)
GraphIdSet:set of byte;
CharWidth,CharHeight:byte;
(* Width and Height in text mode *)
GraphWidth,GraphHeight:word;
(* Width and height in graphics *)
{$IFDEF DEMO}
DWString:array[1..35] of word; (* Used for text writing *)
const
TVGraphAd:array[1..29] of Vector=
((X1:220;Y1:125;X2:240;Y2:125), (*T2*)
(X1:230;Y1:125;X2:230;Y2:150),
(X1:245;Y1:125;X2:255;Y2:150), (*V2*)
(X1:255;Y1:150;X2:265;Y2:125),
(X1:290;Y1:125;X2:280;Y2:125), (*G7*)
(X1:280;Y1:125;X2:270;Y2:130),
(X1:270;Y1:130;X2:270;Y2:145),
(X1:270;Y1:145;X2:280;Y2:150),
(X1:280;Y1:150;X2:290;Y2:150),
(X1:290;Y1:150;X2:290;Y2:140),
(X1:290;Y1:140;X2:280;Y2:140),
(X1:295;Y1:150;X2:295;Y2:125), (*R6*)
(X1:295;Y1:125;X2:305;Y2:125),
(X1:305;Y1:125;X2:315;Y2:130),
(X1:315;Y1:130;X2:315;Y2:135),
(X1:315;Y1:135;X2:295;Y2:140),
(X1:305;Y1:140;X2:315;Y2:150),
(X1:320;Y1:150;X2:320;Y2:135), (*A5*)
(X1:320;Y1:135;X2:330;Y2:125),
(X1:330;Y1:125;X2:340;Y2:135),
(X1:340;Y1:135;X2:340;Y2:150),
(X1:320;Y1:140;X2:340;Y2:140),
(X1:345;Y1:150;X2:345;Y2:125), (*P4*)
(X1:345;Y1:125;X2:365;Y2:125),
(X1:365;Y1:125;X2:365;Y2:140),
(X1:365;Y1:140;X2:345;Y2:140),
(X1:370;Y1:125;X2:370;Y2:150), (*H3*)
(X1:390;Y1:125;X2:390;Y2:150),
(X1:370;Y1:137;X2:390;Y2:137));
AdvertText:array[1..9] of string[35]=
(' Graphics in TURBOVISION ',
' Copyright 1991 ',
'C.L.Burke of MindWare QLD Australia',
'R.A.Morris of KHIRON QLD Australia ',
' The Wizards of Oz ',
' AND COMING SOON ',
' GWHIZ graphics objects in the ',
' spirit of TurboVision ',
' PRESS ANY KEY TO CONTINUE ');
{$ENDIF}
procedure DisableInterrupts; inline($FA);
procedure EnableInterrupts; inline($FB);
procedure MouseCursorOff;assembler;
asm
mov ax,0002h
cli
pushf
call [OldInt33h]
sti
end;
procedure MouseCursorOn;assembler;
asm
mov ax,0001h
cli
pushf
call [OldInt33h]
sti
end;
{$I TVGRAPH.IN0} (* Display Identify routines *)
{$I TVGRAPH.IN1} (* Display Specific routines *)
{$IFDEF DEMO}
procedure RawWriteString(X,Y:Word;S:String);
const
NormTextColor=$1A00;
var
ScrLoc:word;
Cnt:word;
begin
ScrLoc:=Y*160+X*2;
for Cnt:=1 to 35 do
DWString[Cnt]:=NormTextColor+ord(S[Cnt]);
asm
mov si,offset DWString
mov ax,seg DWString
mov di,[ScrLoc]
push ds
mov ds,ax
mov cx,35
call [Do_GraphMOV_X]
pop ds
end;
end;
procedure Advertisement;
const
BorderColor=15;
BackgroundColor=1;
VectorColor=14;
var
XL,XH,YL,YH:word;
Cnt:word;
begin
for cnt:=0 to 3 do
RawDrawLine(170-Cnt,100-Cnt,470+Cnt,100-Cnt,BorderColor);
for cnt:=0 to 3 do
RawDrawLine(470+Cnt,100-Cnt,470+Cnt,300+Cnt,BorderColor);
for cnt:=0 to 3 do
RawDrawLine(470+Cnt,300+Cnt,170-Cnt,300+Cnt,BorderColor);
for cnt:=0 to 3 do
RawDrawLine(170-Cnt,300+Cnt,170-Cnt,100-Cnt,BorderColor);
for Cnt:=101 to 299 do
RawDrawLine(171,Cnt,469,Cnt,BackGroundColor);
for Cnt:=1 to 29 do
With TvGraphAd[Cnt] do
begin
RawDrawLine(X1+9,Y1-10,X2+9,Y2-10,VectorColor);
RawDrawLine(X1+10,Y1-11,X2+10,Y2-11,VectorColor);
RawDrawLine(X1+10,Y1-10,X2+10,Y2-10,VectorColor);
RawDrawLine(X1+10,Y1-9,X2+10,Y2-9,VectorColor);
RawDrawLine(X1+11,Y1-10,X2+11,Y2-10,VectorColor);
end;
XL:=(175 div Charwidth)+1;
XH:=(465 div Charwidth)-1;
YL:=(140 div CharHeight);
YH:=(295 div CharHeight)-1;
for cnt:=1 to 9 do
RawWriteString(XL+1,YL+cnt,AdvertText[cnt]);
asm
mov ax,0
int 16h
end;
end;
{$ENDIF}
function NextGraphId:byte;
var
I:byte;
Found:boolean;
begin
I:=0;
repeat
Inc(I);
Found:=not (I in GraphIdSet);
until (I=254) or found;
NextGraphId:=I;
end;
procedure UseGraphId(b:byte);
begin
GraphIdSet:=GraphIdSet+[b];
CurrentGraphWindow:=b;
end;
procedure ReleaseGraphId(b:byte);
begin
GraphIdSet:=GraphIdSet-[b];
end;
function GraphIdAt(X,Y:integer):byte;
begin
X:=X div CharWidth;
Y:=Y div CharHeight;
GraphIdAt:=GraphWriteAvail[Y*ScreenWidth+X]
end;
function ISin(X:integer):integer; assembler;
asm
(* X is number of 16ths of a degree *)
mov bx,OFFSET SineTable
mov ch,1 (* sign of result *)
mov si,[X]
test si,08000h
jz @L01
neg ch (* negative SIN(-A) = -SIN(A) *)
neg si (* Angle is positive *)
@L01:cmp si,16*360
jl @L02
sub si,16*360
jmp @L01
@L02:cmp si,16*180 (* Angle is 0..359 *)
jl @L03
neg ch
sub si,16*180 (* angle is 0..180 *)
@L03:cmp si,16*90
jle @L04
neg si
add si,16*180
@L04:mov cl,3 (* angle is 0..90 *)
shr si,cl
shl si,1
mov ax,[BX+SI]
test ch,080h
jz @L05
neg ax
@L05:
end;
function ICos(X:integer):integer;
begin
ICos:=ISin(X+90*16);
end;
procedure ClearWindow(Bounds:TRect;Color:word);
var
Cnt:word;
begin
for Cnt:=Bounds.A.Y to Bounds.B.Y do
RawDrawLine(Bounds.A.X,Cnt,Bounds.B.X,Cnt,Color);
end;
procedure New_INT10h; assembler;
asm
(* Replace INT10 to emulate cursor stuff *)
push ds
pushf
push si
mov si,seg @Data
mov ds,si
pop si
cmp ah,1
jne @NOT1
call [TvGraphCursorOff_X]
test cx,0E0E0h
jnz @NoTrans
push ax
mov ah,[CharHeight]
dec ah (* AH= max cursor line *)
sub ah,cl (* Difference between max line and request e.g. -2*)
cmp cl,7
jle @CL_OK
add cl,ah
@CL_OK:
cmp ch,7
jle @CH_OK
add ch,ah
@CH_OK:
pop ax
@NoTrans:
mov [TvGraphCursor],cx
call [TvUpdateCursor_X]
jmp @DOIRET
@NOT1:
cmp ah,2
jne @NOT2
call [TvGraphCursorOff_X]
mov [TvGraphLoc],dx
call [TvUpdateCursor_X]
jmp @DOIRET
@NOT2:
cmp ah,3
jne @NOT3
mov dx,[TvGraphLoc]
mov cx,[TvGraphCursor]
jmp @DOIRET
@NOT3:
call [OldInt10h]
pop ds
iret
@DOIRET:
popf
pop ds
iret
end;
procedure New_EventHandler;assembler;
asm
(* Old event handler divides mouse co-ordinates by 8 all the time *)
(* New Event handler which multiplies by 8 and divides by character *)
(* and then calls the old event handler resulting in the correct *)
(* division. *)
push si
push ax
push bx
mov si,seg @Data
mov ds,si
mov [GraphMouseLoc.X],cx
mov [GraphMouseLoc.Y],dx
mov ax,8
mul dx (* DX:AX = 8*Y *)
xor bh,bh
mov bl,[CharHeight]
div bx (* DX:AX = 8*Y/CharHeight *)
mov dx,ax (* DX = 8*Y/CharHeight *)
push dx
mov ax,8 (* X co-ord *)
mul cx (* AX = X*8 *)
xor bh,bh
mov bl,[CharWidth]
div bx (* AX = X*8/CharWidth *)
mov cx,ax (* X <- X*8/CharWidth *)
pop dx
pop bx
pop ax
pop si
jmp dword [GTVEventRoutine]
end;
procedure New_INT33h; assembler;
(* New mouse interrupt handler to fix graphics *)
asm
cli
push ds
pushf (* call interrupt will call as INT 33h *)
push ax
mov ax,seg @Data
mov ds,ax
pop ax
cmp ax,0ch
jz @change1
call [OldInt33h]
pop ds
sti
iret
@Change1: (* Intercept the change Event routine and save the values *)
mov [GTVEventMask],CX
mov cx,es
mov [GTVEventRoutine.S],Cx
mov [GTVEventRoutine.O],Dx
mov CX,[GTVEventMask]
mov dx,SEG New_EventHandler (*our Event handler *)
mov es,dx
mov dx,OFFSET New_EventHandler
call [OldInt33h] (* has been intercepted *)
pop ds
sti
iret
end;
(* Turn off Events *)
procedure ResetMouse; assembler;
asm
mov ax,0
int 33h
ret
end;
(* Normal text mode video routines *)
procedure SetVidParams(var Smode,Cline:word);
begin
asm
les bx,Smode
mov ax,es:[bx]
mov ah,0
int 10h
mov ah,1
les bx,Cline
mov cx,es:[bx]
int 10h
end;
end;
procedure GetVidParams(var Smode,Cline:word);
begin
asm
mov ah,0fh (* Save video mode *)
int 10h
mov ah,0
les bx,Smode
mov es:[bx],ax
mov ah,03h
int 10h
les bx,Cline
mov es:[bx],cx
end;
end;
(* Copy ROM font table to RAM *)
procedure CopyROMfont;
var
FontPtr:pointer;
Cnt:byte;
begin
FontPtr:=RomFont;
for cnt:=0 to 255 do
begin
move(FontPtr^,FontTable[cnt],CharHeight); (* Insert New Jump for GRAPH_MOV *)
inc(longint(FontPtr),CharHeight);
end;
PtrFontTable:=@FontTable;
end;
(* This function replaces the DoneVideo procedure command in Drivers *)
procedure Do_DoneVideo;
var
CLine,SMode:word;
begin
Do_DONE_X;
DisableInterrupts;
Int33h:=OldInt33h;
Int10h:=OldInt10h;
EnableInterrupts;
SetVidParams(StartupMode,CursorLines);
end;
(* This code is copied over start of the DoneVideo procedure in Drivers *)
procedure NewJmp_DoneVideo; assembler;
asm
jmp far ptr Do_DoneVideo (* 5 *)
end; (*TOTAL 5 bytes*)
(* This function replaces the SetVideoMode procedure command in Drivers *)
procedure Do_SetVideoMode(Mode:word);
var
Driver:Vsystem;
begin
Driver := WhatVsystem;
if hi(Mode)=$01 then HiresScreen:=TRUE;
Mode:=Mode and $FF;
if (Mode>$13) or
not (Driver in GraphScreenInfo[Mode].SuitableAdapters) or
(GraphScreenInfo[Mode].ScreenSeg= $0000) then
begin
case Driver of
Mono,Herc:Mode:=smMono;
EGA:Mode:=smEGA;
VGA:Mode:=smVGA;
else Mode:=smCO80;
end;
end;
if GraphScreenInfo[Mode].ScreenWriteType=_GRAPHICS then
begin
case Mode of
smEGA:Do_Set_EGAVGA;
smVGA:Do_Set_EGAVGA;
end;
ScreenMode:=Mode;
SetVidParams(ScreenMode,CursorLines);
P1:=@Views.Tview.Init;
dec(PtrRec(P1).O,OfsFromInit);
P2:=NewJmp_GraphMOV_X;
move(P2^,P1^,13); (* Insert New Jump for GRAPH_MOV *)
HiresScreen:=FALSE;
CharWidth:=8;
CharHeight:=Mem[$40:$85];
ScreenWidth:=GraphScreenInfo[Mode].Xres div CharWidth;
ScreenHeight:=GraphScreenInfo[Mode].YRes div CharHeight;
GraphWidth:=GraphScreenInfo[Mode].Xres;
GraphHeight:=GraphScreenInfo[Mode].YRes;
CheckSnow:=TRUE;
BytesPerLine:= ScreenWidth;
VideoBufferSeg:=GraphScreenInfo[Mode].ScreenSeg;
TvViziFlag:=0;
TvGraphLoc:=0;
TvGraphCursor:=$2000;
asm
call [TvUpdateCursor_X];
end;
ScreenBuffer:=Ptr(GraphScreenInfo[Mode].ScreenSeg,$0000);
Do_INIT_X;
end else
begin
Do_DONE_X;
SetVidParams(StartupMode,CursorLines);
writeln('That mode not supported in TVGRAPH yet ');
writeln;
halt(255);
end;
end;
(* This code is copied over start of the SetVideoMode procedure in Drivers *)
procedure NewJmp_SetVideoMode; assembler;
asm
jmp far ptr Do_SetVideoMode (* 5 *)
end; (*TOTAL 5 bytes*)
(* This function replaces the InitVideo procedure command in Drivers *)
procedure Do_InitVideo;
begin
ResetMouse;
GetVidParams(StartupMode,CursorLines);
Do_SetVideoMode(smGraphAutoDetect);
{ Do_SetVideoMode(smEGA);}
DisableInterrupts;
OldInt33h:=Int33h;
OldInt10h:=Int10h;
Int33h:=@New_Int33h;
Int10h:=@New_Int10h;
EnableInterrupts;
CopyROMFont;
{$IFDEF DEMO}
fillchar(GraphWriteAvail,sizeof(GraphWriteAvail),#1);
AdVertisement;
{$ENDIF}
fillchar(GraphWriteAvail,sizeof(GraphWriteAvail),#0);
end;
(* This code is copied over start of the InitVideo procedure in Drivers *)
procedure NewJmp_InitVideo; assembler;
asm
jmp far ptr Do_InitVideo (* 5 *)
end; (*TOTAL 5 bytes*)
function RegionOf(X,Y:integer;WX1,WY1,WX2,WY2:integer):byte; assembler;
asm
xor ch,ch
mov ax,[X]
cmp ax,[WX1]
jge @RO1
or ch,0001B
@RO1:
cmp ax,[WX2]
jle @RO2
or ch,0100B
@RO2:
mov ax,[Y]
cmp ax,[WY1]
jge @RO3
or ch,0010B
@RO3:
cmp ax,[WY2]
jle @RO4
or ch,1000B
@RO4:
mov al,ch
end;
procedure SwapInts(var A,B:integer);assembler;
asm
push ds
les si,A
lds di,B
mov ax,es:[si]
xchg ax,[di]
mov es:[si],ax
pop ds
end;
procedure SwapBytes(var A,B:byte);assembler;
asm
push ds
les si,A
lds di,B
mov al,es:[si]
xchg al,[di]
mov es:[si],al
pop ds
end;
procedure ClipPoint(var A1,B1:integer;A2,B2,L:integer);
(* Applies the following formula for extending A1,B1 along *)
(* a line such that B1=L *)
var
T0:longint;
T1,T2:integer;
begin
T1:=A2-A1;
T2:=L-B1;
T0:=LongMul(T1,T2);
T1:=B2-B1;
if T1<>0 then
A1:=A1+LongDiv(T0,T1);
B1:=L;
end;
function ClipLine(var X1,Y1,X2,Y2:integer;var R:TRect):boolean;
var
Inside,Outside:boolean;
Ocu1,Ocu2:byte;
begin
Ocu1:=RegionOf(X1,Y1,R.A.X,R.A.Y,R.B.X,R.B.Y);
Ocu2:=RegionOf(X2,Y2,R.A.X,R.A.Y,R.B.X,R.B.Y);
Inside:=((Ocu1 or Ocu2) = 0);
Outside:=((Ocu1 and Ocu2) <> 0);
while not Inside and not Outside do
begin
if Ocu1=0 then
begin
SwapInts(X1,X2);
SwapInts(Y1,Y2);
SwapBytes(Ocu1,Ocu2);
end;
if ((Ocu1 and $01)<>0) then
ClipPoint(Y1,X1,Y2,X2,R.A.X)
else if ((Ocu1 and $02)<>0) then
ClipPoint(X1,Y1,X2,Y2,R.A.Y)
else if ((Ocu1 and $04)<>0) then
ClipPoint(Y1,X1,Y2,X2,R.B.X)
else if ((Ocu1 and $08)<>0) then
ClipPoint(X1,Y1,X2,Y2,R.B.Y);
Ocu1:=RegionOf(X1,Y1,R.A.X,R.A.Y,R.B.X,R.B.Y);
Ocu2:=RegionOf(X2,Y2,R.A.X,R.A.Y,R.B.X,R.B.Y);
Inside:=((Ocu1 or Ocu2) = 0);
Outside:=((Ocu1 and Ocu2) <> 0);
end;
ClipLine:=Inside;
end;
procedure NoClipDrawLine(X1,Y1,X2,Y2:integer;Color:word);
begin
if X1=X2 then
Draw_Vert_Line_X(X1,Y1,Y2,Color)
else if Y1=Y2 then
Draw_Horiz_Line_X(X1,X2,Y1,Color)
else Draw_Any_Line_X(X1,Y1,X2,Y2,Color);
end;
procedure GlobalToPhysical(Var X,Y:integer);
var
T:Longint;
begin
T:=longmul(X,GraphWidth);
X:=longdiv(T,GraphXMax);
T:=longmul(Y,GraphHeight);
Y:=longdiv(T,GraphYMax);
end;
procedure RawDrawLine(X1,Y1,X2,Y2:integer;Color:word);
var
MR,R:TRect;
LineThruMouse:boolean;
X1M,X2M,Y1M,Y2M:integer;
(* MR is mouse rectangle, R is Window rectangle *)
begin
R.Assign(0,0,GraphWidth-1,GraphHeight-1);
if ClipLine(X1,Y1,X2,Y2,R) then (* Line is visible *)
begin
with GraphMouseLoc do
begin
LineThruMouse:=(GraphIdAt(X-3,Y-3)=CurrentGraphWindow) or
(GraphIdAt(X+16,Y-3)=CurrentGraphWindow) or
(GraphIdAt(X-3,Y+16)=CurrentGraphWindow) or
(GraphIdAt(X+16,Y+16)=CurrentGraphWindow);
MR.Assign(X-3,Y-3,X+16,Y+16);
end;
X1M:=X1;X2M:=X2;Y1M:=Y1;Y2M:=Y2;
if LineThruMouse then
LineThruMouse:=ClipLine(X1M,Y1M,X2M,Y2M,MR);
if X1>X2 then
begin
SwapInts(X1,X2);
SwapInts(Y1,Y2);
end else if (X1=X2) and (Y1>Y2) then SwapInts(Y1,Y2);
if LineThruMouse then
MouseCursorOff;
NoClipDrawLine(X1,Y1,X2,Y2,Color);
if LineThruMouse then
MouseCursorOn;
end;
end;
procedure DrawLine(X1,Y1,X2,Y2:integer;Color:word);
begin
GlobalToPhysical(X1,Y1);
GlobalToPhysical(X2,Y2);
RawDrawLine(X1,Y1,X2,Y2,Color);
end;
procedure PhysicalToGlobal(Var P:GPoint);
var
T:Longint;
begin
with P do
begin
T:=longmul(X,GraphXMax);
X:=longdiv(T,GraphWidth);
T:=longmul(Y,GraphYMax);
Y:=longdiv(T,GraphHeight);
end;
end;
procedure TextToGraphics(T:TRect;var G:GRect);
begin
G.A.X:=T.A.X*CharWidth;
G.A.Y:=T.A.Y*CharHeight;
G.B.X:=T.B.X*CharWidth;
G.B.Y:=T.B.Y*CharHeight;
PhysicalToGlobal(GPoint(G.A));
PhysicalToGlobal(GPoint(G.B));
end;
begin
(* overwrite the start of each of the main functions *)
P1:=@Drivers.InitVideo;
P2:=@NewJmp_InitVideo;
move(P2^,P1^,5);
P1:=@Drivers.SetVideoMode;
P2:=@NewJmp_SetVideoMode;
move(P2^,P1^,5);
P1:=@Drivers.DoneVideo;
P2:=@NewJmp_DoneVideo;
move(P2^,P1^,5);
fillchar(graphidset,sizeof(graphidset),#0);
end.